<script lang="ts" setup>
import type { UnwrapRef } from 'vue';
import { cloneDeep } from 'lodash-es';
import { Modal, message } from 'ant-design-vue';
import ExcelJS from 'exceljs';
import history from './components/history.vue';
import statistical from './components/statistical.vue';
import { useSendMessage } from './useSendMessage';
import { useUpload } from './useUpload';
import { useDownload } from './usedownload';
import useUserStore from '@/store/modules/user';
import { addCGMessage, deleteCGMessage, deleteCGMessageByIds, getCGMessageByPage, getCGMessageByPageDown, getCGMessageByPageUP, updateCGMessage } from '@/api/modules/rbac/dcp/message_management';

const userStore = useUserStore();
const userId = ref<string>('');
const account = ref<string>('');
const orgName = ref<string>('');
// 表格
const data = ref<any[]>([]);
const loading = ref<boolean>(false);
const total = ref<number>(0);
const current = ref<number>(1);
const pageSize = ref<number>(10);
const sort = ref<any>('1');
async function getData() {
  loading.value = true;
  if (sort.value === '1') {
    await getCGMessageByPage(current.value, pageSize.value).then((res: any) => {
      data.value = res.data.records;
      total.value = res.data.total;
    }).finally(() => {
      loading.value = false;
    });
  }
  else if (sort.value === '2') {
    await getCGMessageByPageUP(current.value, pageSize.value).then((res: any) => {
      data.value = res.data.records;
      total.value = res.data.total;
    }).finally(() => {
      loading.value = false;
    });
  }
  else if (sort.value === '3') {
    await getCGMessageByPageDown(current.value, pageSize.value).then((res: any) => {
      data.value = res.data.records;
      total.value = res.data.total;
    }).finally(() => {
      loading.value = false;
    });
  }
}
watch(
  () => sort.value,
  async () => {
    getData();
  },
  { deep: true },
);
async function handleTableChange(pagination: any) {
  pageSize.value = pagination.pageSize;
  current.value = pagination.current;
  getData();
}
const historyRef = ref<InstanceType<typeof history> | null>(null);
onMounted(() => {
  // 获取发送人信息
  userId.value = userStore.userId;
  account.value = userStore.account;
  orgName.value = userStore.userOrgName;
  getData();
});
const columns: any = [
  {
    title: '序号',
    dataIndex: 'id',
    key: 'id',
    width: '100px',
    align: 'center',
  },
  {
    title: '手机号',
    dataIndex: 'phoneNumber',
    key: 'phoneNumber',
    width: '30%',
    align: 'center',
  },
  {
    title: '发送信息',
    dataIndex: 'messageContent',
    key: 'messageContent',
    align: 'center',
  },
  {
    title: '操作',
    dataIndex: 'operation',
    key: 'operation',
    width: '10%',
    align: 'center',
  },
];

// 获取当前时间
function getCurrentTimeFormatted(): string {
  const now = new Date();
  const year = now.getFullYear();
  const month = String(now.getMonth() + 1).padStart(2, '0');
  const day = String(now.getDate()).padStart(2, '0');
  const hours = String(now.getHours()).padStart(2, '0');
  const minutes = String(now.getMinutes()).padStart(2, '0');
  const seconds = String(now.getSeconds()).padStart(2, '0');
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
async function add() {
  await addCGMessage('', '', getCurrentTimeFormatted());
  getData();
}
async function claer(id: number) {
  await deleteCGMessage(id);
  getData();
}

// 编辑
const editableDataP: UnwrapRef<Record<string, any>> = reactive({});
function editP(id: string) {
  editableDataP[id] = cloneDeep(data.value.filter(item => id === item.id)[0]);
}
async function saveP(id: string) {
  const item = Object.assign(data.value.filter(item => id === item.id)[0], editableDataP[id]);
  await updateCGMessage(item.id, item.phoneNumber, item.messageContent);
  delete editableDataP[id];
}

const editableDataM: UnwrapRef<Record<string, any>> = reactive({});
function editM(id: string) {
  editableDataM[id] = cloneDeep(data.value.filter(item => id === item.id)[0]);
}
async function saveM(id: string) {
  const item = Object.assign(data.value.filter(item => id === item.id)[0], editableDataM[id]);
  await updateCGMessage(item.id, item.phoneNumber, item.messageContent);
  delete editableDataM[id];
}

// 选择
const selectedRowKeys = ref<any[]>([]);
const sloading = ref<boolean>(false);
const hasSelected = computed(() => selectedRowKeys.value.length > 0);
function onSelectChange(Keys: any[]) {
  selectedRowKeys.value = Keys;
}
// 发送方式
const way = ref<string>('server');
// 发送短信
async function send() {
  const items = [];
  for (let i = 0; i < selectedRowKeys.value.length; i++) {
    const item = data.value.find(message => message.id === selectedRowKeys.value[i]);
    items.push({
      accNbr: item.phoneNumber,
      orderContent: item.messageContent,
      requestTime: useSendMessage().getCurrentTimeFormatted(),
      sender: `${account.value}(${userId.value})`,
    });
  }
  if (way.value === 'server') {
    try {
      const result = await useSendMessage().sendMessageByServer(items);
      if (result === true) {
        for (let i = 0; i < selectedRowKeys.value.length; i++) {
          claer(selectedRowKeys.value[i]);
        }
        getData();
      }
    }
    catch (error) {
      console.error(error);
    }
  }
  else {
    // 遍历本机发送短信+添加记录
    for (let i = 0; i < items.length; i++) {
      try {
        const result = await useSendMessage().sendMessage(items[i].accNbr, items[i].orderContent, items[i].requestTime);
        if (result === true) {
          for (let i = 0; i < selectedRowKeys.value.length; i++) {
            claer(selectedRowKeys.value[i]);
          }
          getData();
        }
      }
      catch (error) {
        console.error(error);
      }
    }
  }
}
async function start() {
  sloading.value = true;
  await send();
  if (historyRef.value) {
    historyRef.value.getData();
  }
  sloading.value = false;
  selectedRowKeys.value = [];
}

// excel文件上传
const fileList = ref<any>([]);

// 移除文件
function handleRemove(file: any) {
  const index = fileList.value.findIndex((f: { uid: any }) => f.uid === file.uid);
  fileList.value.splice(index, 1);
}

// 阻止自动上传
function beforeUpload(file: any) {
  fileList.value = [];
  fileList.value.push(file);
  return false; // 阻止自动上传
}
// 清空草稿数据库
async function clearCG() {
  let items: any[] = [];
  const ids: any[] = [];
  await getCGMessage().then((res: any) => {
    items = res.data;
  });
  if (items.length > 0) {
    items.forEach(async (item: any) => {
      if (item.isDelete === 0) {
        ids.push(item.id);
      }
    });
    // 删除
    await deleteCGMessageByIds(ids);
  }
}
// 手动上传
async function handleManualUpload() {
  if (fileList.value.length === 0) {
    message.error('请上传文件！');
    return;
  }
  await fileList.value.forEach(async (file: any) => {
    // 判断文件类型
    if (useUpload().checkIfExcel(file.name || '')) {
      const formData = new FormData();
      formData.append('file', file);
      // 先将数据显示在页面中
      const reader = new FileReader();
      reader.onload = async (e) => {
        const buffer: any = e.target?.result;
        if (buffer) {
          const workbook = new ExcelJS.Workbook();
          await workbook.xlsx.load(buffer).then(async () => {
            const worksheet: any = workbook.getWorksheet(1);
            const headers: any[] = [];
            worksheet?.getRow(1).eachCell((cell: { value: any }) => {
              if (useUpload().isLetter(cell.value)) {
                headers.push(cell.value.toLowerCase());
              }
              else {
                headers.push(cell.value);
              }
            });
            const title = [
              '手机号',
              '发送信息',
            ];
            // 拦截错误的表格
            if (!useUpload().areArraysEqualIgnoreOrder(title, headers)) {
              message.error('excel内表格的字段数或表头出错,上传失败！');
              loading.value = false;
              return;
            }
            // 清空草稿数据库
            await clearCG();
            // 上传到数据库
            await messageFileupload(formData).then(() => {
              message.success('上传成功！');
              // 移除文件
              handleRemove(file);
              // 更新数据
              addExcelData();
            })
              .catch(() => {
                message.error('上传失败');
                // 重新更新数据，将原先显示在页面的数据撤回
                getData();
              });
          });
        }
      };
      reader.readAsArrayBuffer(file);
    }
    else {
      message.error('请上传execl文件！');
    }
  });
}
// 把上传草稿的内容放到data中
async function addExcelData() {
  getData();
}
// 模板下载
async function downExcel() {
  await useDownload().downExcel();
}
function info() {
  Modal.info({
    title: () => '发送人信息',
    content: () => h('div', {}, [
      h('p', `用户名:${account.value}`),
      h('p', `ID:${userId.value}`),
      h('p', `所属组织:${orgName.value}`),
    ]),
  });
}
async function sendAll() {
  await sendMoreMessage().then(async () => {
    await clearCG();
    getData();
    if (historyRef.value) {
      historyRef.value.getData();
    }
  });
}
</script>

<template>
  <PubPageMain class="max">
    <div class="header">
      <div class="left">
        <a-space>
          <div class="pjTitle">
            短信发送
          </div>
          <div v-if="selectedRowKeys.length !== 0" style="margin-left: 10px;">
            已选中{{ selectedRowKeys.length }}条短信
          </div>
        </a-space>
      </div>
      <div class="right">
        <a-space>
          <div style="margin-top: 10px;margin-right: 2.667vw;">
            发送人：<span style="cursor: pointer;" @click="info()">{{
              account }}</span>
          </div>
          <a-upload
            :file-list="fileList" :before-upload="beforeUpload" name="file" :multiple="false" action=""
            accept=".xlsx, .xls" :on-remove="handleRemove"
          >
            <a-button>
              <upload-outlined /> 点击选择文件
            </a-button>
          </a-upload>
          <a-button type="primary" @click="handleManualUpload">
            上传至草稿
          </a-button>
          <a-button type="primary" @click="downExcel">
            下载模板
          </a-button>
          <a-button v-if="data.length === 0" type="primary" @click="add">
            添加
          </a-button>
          <a-button v-if="data.length !== 0" type="primary" @click="sendAll">
            全部发送
          </a-button>
          <!-- <a-radio-group v-model:value="way">
            <a-radio-button value="thisDevice">
              本机发送
            </a-radio-button>
            <a-radio-button value="server">
              服务器发送
            </a-radio-button>
          </a-radio-group> -->
        </a-space>
      </div>
    </div>
    <div>
      <span v-if="data.length !== 0" style="display: flex;justify-content: end;">
        <a-radio-group v-model:value="sort">
          <a-radio-button value="1">默认</a-radio-button>
          <a-radio-button value="2">升序</a-radio-button>
          <a-radio-button value="3">降序</a-radio-button>
        </a-radio-group>
      </span>
    </div>
    <div class="content">
      <a-table
        :columns="columns" :data-source="data" row-key="id" class="d-table" :loading="loading"
        :pagination="{ pageSize, showQuickJumper: true, total }"
        :row-selection="{ selectedRowKeys, onChange: onSelectChange }" @change="handleTableChange"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.dataIndex === 'phoneNumber'">
            <div class="editable-cell">
              <div v-if="editableDataP[record.id]" class="editable-cell-input-wrapper">
                <a-input v-model:value="editableDataP[record.id].phoneNumber" @press-enter="saveP(record.id)">
                  <template #suffix>
                    <check-outlined class="editable-cell-icon-check" @click="saveP(record.id)" />
                  </template>
                </a-input>
              </div>
              <div v-else class="editable-cell-text-wrapper">
                <div>
                  <a-input v-model:value="record.phoneNumber" :disabled="true" class="disabled-input">
                    <template #suffix>
                      <edit-outlined class="editable-cell-icon" @click="editP(record.id)" />
                    </template>
                  </a-input>
                </div>
              </div>
            </div>
          </template>
          <template v-if="column.dataIndex === 'messageContent'">
            <div class="editable-cell">
              <div v-if="editableDataM[record.id]" class="editable-cell-input-wrapper">
                <a-input v-model:value="editableDataM[record.id].messageContent" @press-enter="saveM(record.id)">
                  <template #suffix>
                    <check-outlined class="editable-cell-icon-check" @click="saveM(record.id)" />
                  </template>
                </a-input>
              </div>
              <div v-else class="editable-cell-text-wrapper">
                <a-input v-model:value="record.messageContent" :disabled="true" class="disabled-input">
                  <template #suffix>
                    <edit-outlined class="editable-cell-icon" @click="editM(record.id)" />
                  </template>
                </a-input>
              </div>
            </div>
          </template>
          <template v-if="column.dataIndex === 'operation'">
            <span>
              <a-space>
                <PlusCircleOutlined style=" font-size: 20px; color: #47d232;cursor: pointer;" @click="add" />
                <MinusCircleOutlined style="font-size: 20px;color: red;cursor: pointer;" @click="claer(record.id)" />
              </a-space>
            </span>
          </template>
        </template>
      </a-table>
    </div>
    <div class="send-button">
      <a-button type="primary" :loading="sloading" :disabled="!hasSelected" style="margin-right: 10px;" @click="start">
        发送
      </a-button>
    </div>
    <a-divider />
    <statistical />
    <a-divider />
    <history ref="historyRef" />
  </PubPageMain>
</template>

<style lang="scss" scoped>
.max {
  display: flex;
  flex-direction: column;
  max-width: 100%;
  max-height: 95%;
  overflow: auto;

  .header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    height: 31px;
    margin-bottom: 10px;

    .pjTitle {
      padding-left: 15px;
      background: url("@/assets/images/title-left-bg.svg") no-repeat;
    }

    .right {
      display: flex;
      align-items: center;
    }
  }

  .content {
    display: flex;
    flex: 1;
    flex-direction: column;
    width: 100%;
    height: 95%;
    overflow: auto;
    overflow-y: auto;

    .d-table {
      flex-grow: 1;
      height: 100%;
      max-height: 100%;
      padding: 10px;
    }
  }

  .send-button {
    display: flex;
    justify-content: flex-end;
  }
}

.editable-cell {
  position: relative;

  .editable-cell-text-wrapper {
    width: 100%;
    height: 100%;
  }

  .editable-cell-icon,
  .editable-cell-icon-check {
    font-size: 20px;
    cursor: pointer;
  }

  .editable-cell-icon {
    display: none;
  }

  .editable-cell-icon-check {
    line-height: 28px;
  }

  .editable-cell-icon:hover,
  .editable-cell-icon-check:hover {
    color: #108ee9;
  }

  .editable-add-btn {
    margin-bottom: 8px;
  }
}

.editable-cell:hover .editable-cell-icon {
  display: inline-block;
}

.disabled-input {
  background-color: #fff;
}

.ant-upload-wrapper {
  display: flex;
  flex-direction: row-reverse;
  align-items: center;
  height: 31px;
}
</style>
